package com.wanlian.netty.model;

import com.wanlian.File.FileContinueRecord;
import com.wanlian.File.FileUtils;
import com.wanlian.File.NetFileInfo;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class NetFileInfoRecord {
    private long lastTime;
    private List<NetFileInfo> netFileInfos;
    public boolean bEnd;
    public String filePath;
    public long currentIndex;
    public long size;
    public long totalSize;
    private String clientId;
    private FileContinueRecord fileContinueRecord;

    public NetFileInfoRecord() {
        this.lastTime = System.currentTimeMillis();
        this.netFileInfos = new ArrayList<>();
        this.fileContinueRecord = new FileContinueRecord();
    }

    public boolean hasTimeout(int timeout) {
        if (System.currentTimeMillis() - this.lastTime > timeout) {
            return true;
        } else {
            return false;
        }
    }

    public void add(NetFileInfo netFileInfo) {
        this.netFileInfos.add(netFileInfo);
    }

    public synchronized void addAll(List<NetFileInfo> netFileInfos) {
        this.netFileInfos.addAll(netFileInfos);
    }

    public void addAndTidy(List<NetFileInfo> netFileInfos) {
        sortList(netFileInfos);
        List<NetFileInfo> newNetFileInfos = tidyNeedReadLength(netFileInfos);
        this.fileContinueRecord.getNeedContinueFileInfos().addAll(newNetFileInfos);
    }


    /**
     * 对目标队列排序
     *
     * @param netFileInfos
     */
    public void sortList(List<NetFileInfo> netFileInfos) {
        Collections.sort(netFileInfos, new Comparator<NetFileInfo>() {
            @Override
            public int compare(NetFileInfo o1, NetFileInfo o2) {
                if (o1.getCurrentIndex() > o2.getCurrentIndex()) {
                    return 1;
                } else {
                    return -1;
                }
            }
        });
    }

    /**
     * 整合成大长度
     *
     * @param netFileInfos
     * @return
     */
    public List<NetFileInfo> tidyNeedReadLength(List<NetFileInfo> netFileInfos) {
        List<NetFileInfo> newNetFileInfos = new ArrayList<>();
        NetFileInfo netFileInfo = netFileInfos.get(0);
        NetFileInfo currentNode = netFileInfo;
        if(netFileInfos.size()==1) {
            newNetFileInfos.add(currentNode);
        }
        else {
            for (int i = 1; i < netFileInfos.size(); i++) {
                NetFileInfo afterNetFileInfo = netFileInfos.get(i);
                if (!currentNode.checkCanAppendALine(afterNetFileInfo)) {
                    newNetFileInfos.add(currentNode.cope());
                    currentNode=afterNetFileInfo;
                }
                if (i == netFileInfos.size() - 1) {
                    newNetFileInfos.add(currentNode);
                }
            }
        }
        return newNetFileInfos;
    }


    public void remove(int index, int count) {
        for (int i = index + count - 1; i >= 0; i--) {
            this.netFileInfos.remove(i);
        }
        this.lastTime = System.currentTimeMillis();
    }

    public void writeToFile(int count) {
        try {
            if (this.netFileInfos.size() > 0) {
                if (count > this.netFileInfos.size()) {
                    count = this.netFileInfos.size();
                }
                NetFileInfo netFileInfo = this.netFileInfos.get(0);
                for (int i = 1; i < count; i++) {
                    netFileInfo.appendToLine(this.netFileInfos.get(i));
                }
                FileUtils.writeFile(netFileInfo);
                this.remove(0, count);
            }
        } catch (Exception e) {
            throw e;
        }
    }

    public boolean hasContent() {
        if (this.netFileInfos == null) {
            return false;
        } else {
            if (this.netFileInfos.size() == 0) {
                return false;
            }
            return true;
        }
    }

    /**
     * 读取剩余的部分
     */
    public synchronized void readContinueFile() {
        if (!this.fileContinueRecord.isHasRead()) {
            List<NetFileInfo> tags=this.fileContinueRecord.deQueue(100);
            if (tags != null && tags.size() > 0) {
                List<NetFileInfo> continues=  FileUtils.readFileByCurrentIndex(tags);
                for (NetFileInfo netFileInfo:continues) {
                    netFileInfo.setbContinue(true);
                }
                this.addAll(continues);
            }
        }
    }

    public synchronized void readFile() {
        if (this.bEnd) {
            return;
        }
        FileUtils.readFile(this);
    }

    public synchronized List<NetFileInfo> dequeue(int count) {
        if (this.netFileInfos.size() < count) {
            count = this.netFileInfos.size();
        }
        List<NetFileInfo> netFileInfoslst = new ArrayList<>(count);
        for (int i = 0; i < count; i++) {
            netFileInfoslst.add(this.netFileInfos.get(i));
        }
        this.remove(0, count);
        return netFileInfoslst;
    }


    public List<NetFileInfo> getNetFileInfos() {
        return netFileInfos;
    }

    public String getClientId() {
        return clientId;
    }

    public void setClientId(String clientId) {
        this.clientId = clientId;
    }
    public FileContinueRecord getFileContinueRecord() {
        return fileContinueRecord;
    }
}
